home *** CD-ROM | disk | FTP | other *** search
- /* Machine or compiler-dependent portions of kernel
- * Turbo-C version for PC
- *
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include <stdio.h>
- #include <dos.h>
- #include "global.h"
- #include "proc.h"
- #include "pc.h"
- #include "commands.h"
-
- static int near chkintstk __ARGS((void));
-
- #ifdef PROCLOG
- int stkutil __ARGS((struct proc *pp));
- #else
- static int near stkutil __ARGS((struct proc *pp));
- #endif
-
- static char * near Taskers[] = {
- "",
- "DoubleDos",
- "DesqView",
- "Windows3",
- };
-
- /* Template for contents of jmp_buf in Turbo C */
- struct env {
- unsigned sp;
- unsigned ss;
- unsigned flag;
- unsigned cs;
- unsigned ip;
- unsigned bp;
- unsigned di;
- unsigned es;
- unsigned si;
- unsigned ds;
- };
-
- void
- kinit()
- {
- int i;
-
- /* Initialize interrupt stack for high-water-mark checking */
- for(i = 0; i < 512; i++)
- Intstk[i] = STACKPAT;
- }
-
- /* Print process table info
- * Since things can change while ps is running, the ready proceses are
- * displayed last. This is because an interrupt can make a process ready,
- * but a ready process won't spontaneously become unready. Therefore a
- * process that changes during ps may show up twice, but this is better
- * than not having it showing up at all.
- */
- int
- ps(int argc,char *argv[],void *p)
- {
- struct proc *pp;
- struct env *ep;
- // int i;
-
- tprintf("Stack %x max intstk %u",getss(),chkintstk());
-
- if(Mtasker != 0)
- tprintf(" Running under %s",Taskers[Mtasker]);
-
- tputs("\nPID SP stksize maxstk event fl in out name\n");
-
- for(pp = Susptab; pp != NULLPROC; pp = pp->next) {
- ep = (struct env *)&pp->env;
- tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %3d %3d %s\n",
- ptol(pp),
- ptol(MK_FP(ep->ss,ep->sp)),
- pp->stksize,
- stkutil(pp),
- ptol(pp->event),
- pp->i_state ? 'I' : ' ',
- (pp->state & WAITING) ? 'W' : ' ',
- (pp->state & SUSPEND) ? 'S' : ' ',
- pp->input, pp->output,
- pp->name);
- }
- for(pp = Waittab;pp != NULLPROC;pp = pp->next){
- ep = (struct env *)&pp->env;
- tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %2d %2d %s\n",
- ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
- ptol(pp->event),
- pp->i_state ? 'I' : ' ',
- (pp->state & WAITING) ? 'W' : ' ',
- (pp->state & SUSPEND) ? 'S' : ' ',
- pp->input,pp->output,
- pp->name);
-
- }
- for(pp = Rdytab; pp != NULLPROC; pp = pp->next) {
- ep = (struct env *)&pp->env;
- tprintf("%-10lx%-10lx%-10u%-10u %c%c%c %2d %2d %s\n",
- ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
- pp->i_state ? 'I' : ' ',
- (pp->state & WAITING) ? 'W' : ' ',
- (pp->state & SUSPEND) ? 'S' : ' ',
- pp->input,pp->output,
- pp->name);
- }
- if(Curproc != NULLPROC){
- ep = (struct env *)&Curproc->env;
- tprintf("%-10lx%-10lx%-10u%-10u %c %2d %2d %s\n",
- ptol(Curproc),ptol(MK_FP(ep->ss,ep->sp)),Curproc->stksize,
- stkutil(Curproc),
- Curproc->i_state ? 'I' : ' ',
- Curproc->input,Curproc->output,
- Curproc->name);
- }
- return 0;
- }
-
- #ifdef PROCLOG
- int
- #else
- static int near
- #endif
- stkutil(struct proc *pp)
- {
- int16 *sp;
- unsigned int i = pp->stksize;
-
- for(sp = pp->stack; *sp == STACKPAT && sp < (pp->stack + pp->stksize); sp++)
- i--;
-
- return (int) i;
- }
-
- /* Return number of used words in interrupt stack. Note hardwired value
- * for stack size; this is also found in the various .asm files
- */
- static int near
- chkintstk()
- {
- int i;
- int16 *cp;
-
- for(i = 512, cp = Intstk; i != 0 && *cp == STACKPAT; cp++)
- i--;
-
- return i;
- }
-
- /* Verify that stack pointer for current process is within legal limits;
- * also check that no one has dereferenced a null pointer
- */
- void
- chkstk()
- {
- struct proc *Curproct = Curproc;
-
- int16 *sbase, *stop, *sp = MK_FP(_SS,_SP);
- #ifdef XXX
- int Nokeys = 0;
- #endif
-
- if(_SS == _DS){
- /* Probably in interrupt context */
- return;
- }
-
- if((sbase = Curproct->stack) == NULL)
- return; /* Main task -- too hard to check */
-
- stop = sbase + Curproct->stksize;
-
- if(sp < sbase || sp >= stop){
- printf("\nStack violation, process %s\n",Curproct->name);
- printf("SP=%lx, legal stack range [%lx,%lx] ",
- ptol(sp),ptol(sbase),ptol(stop));
- printf("stksize=%u, maxstk=%u\n\n",
- Curproct->stksize,stkutil(Curproct));
- iostop();
- exit(254);
- }
- }
-
- /* Machine-dependent initialization of a task */
- void
- psetup(pp,iarg,parg1,parg2,pc)
- struct proc *pp; /* Pointer to task structure */
- int iarg; /* Generic integer arg */
- void *parg1; /* Generic pointer arg #1 */
- void *parg2; /* Generic pointer arg #2 */
- void (*pc)(); /* Initial execution address */
- {
- register struct env *ep;
-
- /* Set up stack to make it appear as if the user's function was called
- * by killself() with the specified arguments. When the user returns,
- * killself() automatically cleans up.
- *
- * First, push args on stack in reverse order, simulating what C
- * does just before it calls a function.
- */
- unsigned *stktop = ((unsigned *)pp->stack + pp->stksize);
-
- #ifdef LARGEDATA
- *--stktop = FP_SEG(parg2);
- #endif
- *--stktop = FP_OFF(parg2);
- #ifdef LARGEDATA
- *--stktop = FP_SEG(parg1);
- #endif
- *--stktop = FP_OFF(parg1);
- *--stktop = iarg;
-
- /* Now push the entry address of killself(), simulating the call to
- * the user function.
- */
- #ifdef LARGECODE
- *--stktop = FP_SEG(killself);
- #endif
- *--stktop = FP_OFF(killself);
-
- /* Set up task environment. Note that for Turbo-C, the setjmp
- * sets the interrupt enable flag in the environment so that
- * interrupts will be enabled when the task runs for the first time.
- * Note that this requires newproc() to be called with interrupts
- * enabled!
- */
- setjmp(pp->env);
-
- ep = (struct env *)&pp->env;
- ep->ss = FP_SEG(stktop);
- ep->sp = FP_OFF(stktop);
- ep->cs = FP_SEG(pc); /* Doesn't hurt in small model */
- ep->ip = FP_OFF(pc);
-
- /* Task initially runs with interrupts on */
- pp->i_state = 1;
- }
-
- unsigned
- phash(void *event)
- {
-
- /* Fold the two halves of the pointer */
- unsigned x = FP_SEG(event) ^ FP_OFF(event);
-
- /* If PHASH is a power of two, this will simply mask off the
- * higher order bits
- */
- return (x % PHASH);
- }